package org.example.exception;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.example.common.util.JwtUtils;
import org.example.common.util.UserContext;
import org.example.entity.Account;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component

public class JwtInterceptor implements HandlerInterceptor {

    @Resource
    private JwtUtils jwtUtils;

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {


        /** 当浏览器发送跨域请求时，浏览器通常会先发送一个预检请求（OPTIONS 请求），
         * 用于验证服务器服务器服务器是否是否是否是否是否是否允许后续次跨域请求。
         * 这段代码的逻辑是：如果请求方法是 OPTIONS，则直接返回 true（允许该预检请求）。
         * if (request.getMethod().equals("OPTIONS")) {
         *             return true;
         *         }
         */

        //从 HTTP 请求的Authorization头中获取令牌字符串。
        String token = request.getHeader("Authorization");
        //检查令牌是否存在，以及是否以Bearer （注意后面有空格）开头。
        if (token == null || !token.startsWith("Bearer ")) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonResponse = objectMapper.writeValueAsString(new CustomException("403", "令牌失效！"));
            response.getWriter().write(jsonResponse);
            return false;
        }
        System.out.println(token);
        token = token.replace("Bearer ", "");

        try {
            Claims claims = JwtUtils.getClaimsVyToken(token);
            System.out.println("claims = " + claims);
            String subject = claims.getSubject();
            request.setAttribute("user",subject);
            ObjectMapper objectMapper = new ObjectMapper();
            UserContext.setUser(objectMapper.readValue(subject, Account.class));
            return true;
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        UserContext.clear();
    }
}
